package com.zshan.clinic.admin.service.customer;

import com.zshan.clinic.admin.constant.Constants;
import com.zshan.clinic.admin.entity.vo.CmUserPatientVo;
import com.zshan.clinic.admin.service.patient.ClinicPatientService;
import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.enums.GenderEnum;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.page.PageInfo;
import com.zshan.clinic.common.util.page.PageUtils;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.common.util.validate.IdCardUtils;
import com.zshan.clinic.database.dao.CmUserPatientMapper;
import com.zshan.clinic.database.model.ClinicPatient;
import com.zshan.clinic.database.model.CmUserPatient;
import com.zshan.clinic.database.model.CmUserPatientExample;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 就诊人
 */
@Service
@Slf4j
public class CmUserPatientService {

    @Autowired
    private CmUserPatientMapper cmUserPatientMapper;

    @Autowired
    private ClinicPatientService clinicPatientService;

    /**
     * 查询患者列表
     * @param clinicId
     * @param cmUserId
     * @return
     */
    public List<CmUserPatientVo> getPatientList(Long clinicId, Long cmUserId,String isDefault) {
        List<CmUserPatient> patientList = getCmUserPatientListByCmUserId(clinicId,cmUserId,isDefault);
        if(CollectionUtils.isEmpty(patientList)){
            return Collections.EMPTY_LIST;
        }
        // 将实体列表转换为DTO列表
        return patientList.stream().map(patient -> {
            CmUserPatientVo cmUserPatientVo = new CmUserPatientVo();
            BeanUtils.copyProperties(patient, cmUserPatientVo);
            return cmUserPatientVo;
        }).collect(Collectors.toList());
    }

    /**
     * 查询就诊人列表
     * @param clinicId
     * @param cmUserId
     * @return
     */
    public List<CmUserPatient> getCmUserPatientListByCmUserId(Long clinicId, Long cmUserId,String isDefault) {
        CmUserPatientExample example = new CmUserPatientExample();
        CmUserPatientExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andCmUserIdEqualTo(cmUserId);
        if(StringUtil.isNotBlank(isDefault)){
            criteria.andIsDefaultEqualTo(isDefault);
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        return cmUserPatientMapper.selectByExample(example);
    }

    /**
     * 分页查询C端就诊人
     * @param patientName 就诊人姓名（可选条件）
     * @param pageNo 页码
     * @param pageSize 每页条数
     * @return 分页结果
     */
    public PageInfo<CmUserPatient> getCmUserPatientListByCondition(String patientName, Integer pageNo, Integer pageSize) {
        CmUserPatientExample example = new CmUserPatientExample();
        CmUserPatientExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotBlank(patientName)) {
            criteria.andPatientNameLike("%" + patientName + "%");
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        Long totalCount = cmUserPatientMapper.countByExample(example);
        if (totalCount == null || totalCount == 0) {
            return PageInfo.build();
        }
        example.setOffset(PageUtils.getOffset(pageNo, pageSize));
        example.setLimit(pageSize);
        example.setOrderByClause("create_time desc");
        List<CmUserPatient> list = cmUserPatientMapper.selectByExample(example);
        return new PageInfo<>(totalCount, list);
    }

    /**
     * 添加C端就诊人
     * @param cmUserPatient 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void addCmUserPatient(CmUserPatient cmUserPatient) {
        validateCmUserPatient(cmUserPatient);
        //根据身份号和用户ID检查重复性
        CmUserPatient dbCmUserPatient = getCmPatientByIdCard(cmUserPatient.getClinicId(),cmUserPatient.getCmUserId(),cmUserPatient.getIdCard());
        if(dbCmUserPatient != null){
            throw new BusinessFailException("当前身份证号已被占用，请更换后再试！");
        }
        ClinicPatient clinicPatient = getClinicPatientByIdCard(cmUserPatient);
        //诊所的患者ID
        cmUserPatient.setPatientId(clinicPatient.getPatientId());
        Long patientCount = getPatientCountByCmUserId(cmUserPatient.getClinicId(),cmUserPatient.getCmUserId());
        if(patientCount <= CommonConstant.DEFAULT_0){
            cmUserPatient.setIsDefault(YesOrNoEnum.YES.getValue());
        }else {
            cmUserPatient.setIsDefault(YesOrNoEnum.NO.getValue());
        }
        cmUserPatient.setIsDelete(YesOrNoEnum.NO.getValue());
        cmUserPatient.setIsEnabled(YesOrNoEnum.YES.getValue());
        cmUserPatient.setCreateTime(new Date());
        cmUserPatientMapper.insertSelective(cmUserPatient);
    }

    public Long getPatientCountByCmUserId(Long clinicId,Long cmUserId){
        CmUserPatientExample example = new CmUserPatientExample();
        CmUserPatientExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andCmUserIdEqualTo(cmUserId);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        return cmUserPatientMapper.countByExample(example);
    }

    /**
     * 根据身份账号查询患者信息
     * @param cmUserPatient
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ClinicPatient getClinicPatientByIdCard(CmUserPatient cmUserPatient) {
        ClinicPatient clinicPatient = clinicPatientService.getPatientByIdCard(cmUserPatient.getClinicId(),cmUserPatient.getIdCard());
        if(clinicPatient == null){
            clinicPatient = new ClinicPatient();
            clinicPatient.setClinicId(cmUserPatient.getClinicId());
            clinicPatient.setPatientName(cmUserPatient.getPatientName());
            clinicPatient.setPatientGender(cmUserPatient.getPatientGender());
            clinicPatient.setIdCard(cmUserPatient.getIdCard());
            clinicPatient.setAgeYear(cmUserPatient.getAgeYear());
            clinicPatient.setAgeMonth(cmUserPatient.getAgeMonth());
            clinicPatient.setSolarBirthday(cmUserPatient.getSolarBirthday());
            clinicPatient.setLunarBirthday(cmUserPatient.getLunarBirthday());
            clinicPatient = clinicPatientService.addPatient(clinicPatient);
        }
        return clinicPatient;
    }

    public CmUserPatient getCmPatientByIdCard(Long clinicId,Long cmUserId,String idCard){
        CmUserPatientExample example = new CmUserPatientExample();
        CmUserPatientExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andCmUserIdEqualTo(cmUserId);
        criteria.andIdCardEqualTo(idCard);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        List<CmUserPatient> cmUserPatientList = cmUserPatientMapper.selectByExample(example);
        return CollectionUtils.isEmpty(cmUserPatientList) ? null : cmUserPatientList.get(0);
    }

    /**
     * 校验C端就诊人参数
     * @param patient 实体
     */
    public void validateCmUserPatient(CmUserPatient patient) {
        patient.setPatientName(StringUtil.removeAllWhitespace(patient.getPatientName()));
        if (StringUtil.isBlank(patient.getPatientName())) {
            throw new BusinessFailException("姓名不能为空");
        }
        if (patient.getPatientName().length() > Constants.PATIENT_NAME_LENGTH) {
            throw new BusinessFailException("姓名最多"+Constants.PATIENT_NAME_LENGTH+"个字！");
        }
        if(StringUtil.isBlank(patient.getPatientGender())){
            patient.setPatientGender(GenderEnum.UNKNOWN.getValue());
        }
        if(!GenderEnum.isValue(patient.getPatientGender())){
            throw new BusinessFailException("性别错误！");
        }
        if(StringUtil.isBlank(patient.getIdCard())){
            throw new BusinessFailException("请填写身份证号");
        }
        if(!IdCardUtils.isValidFormat(patient.getIdCard())){
            throw new BusinessFailException("身份证号格式错误！");
        }

    }

    /**
     * 根据ID查询C端就诊人
     * @param cmPatientId 主键
     * @return C端就诊人记录
     */
    public CmUserPatient getCmUserPatientById(Long cmPatientId) {
        if (cmPatientId == null) {
            return null;
        }
        CmUserPatient cmUserPatient = cmUserPatientMapper.selectByPrimaryKey(cmPatientId);
        if (cmUserPatient == null || YesOrNoEnum.YES.getValue().equals(cmUserPatient.getIsDelete())) {
            return null;
        }
        return cmUserPatient;
    }

    /**
     * 修改C端就诊人
     * @param cmUserPatient 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateCmUserPatient(CmUserPatient cmUserPatient) {
        validateCmUserPatient(cmUserPatient);
        CmUserPatient dbCmUserPatient = getCmUserPatientById(cmUserPatient.getCmPatientId());
        if (dbCmUserPatient == null) {
            throw new BusinessFailException("就诊人不存在");
        }
        cmUserPatient.setUpdateTime(new Date());
        cmUserPatientMapper.updateByPrimaryKeySelective(cmUserPatient);
        ClinicPatient clinicPatient = new ClinicPatient();
        clinicPatient.setPatientId(dbCmUserPatient.getPatientId());
        clinicPatient.setClinicId(dbCmUserPatient.getClinicId());
        clinicPatient.setPatientName(cmUserPatient.getPatientName());
        clinicPatient.setPatientGender(cmUserPatient.getPatientGender());
        clinicPatient.setIdCard(cmUserPatient.getIdCard());
        clinicPatient.setAgeYear(cmUserPatient.getAgeYear());
        clinicPatient.setAgeMonth(cmUserPatient.getAgeMonth());
        clinicPatient.setSolarBirthday(cmUserPatient.getSolarBirthday());
        clinicPatient.setLunarBirthday(cmUserPatient.getLunarBirthday());
        clinicPatientService.updatePatient(clinicPatient);
    }

    /**
     * 删除C端就诊人（逻辑删除）
     * @param cmUserPatient 实体
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteCmUserPatient(CmUserPatient cmUserPatient) {
        CmUserPatient dbCmUserPatient = getCmUserPatientById(cmUserPatient.getCmPatientId());
        if (dbCmUserPatient == null) {
            throw new BusinessFailException("就诊人不存在");
        }
        dbCmUserPatient.setIsDelete(YesOrNoEnum.YES.getValue());
        dbCmUserPatient.setUpdateUserId(cmUserPatient.getUpdateUserId());
        dbCmUserPatient.setUpdateBy(cmUserPatient.getUpdateBy());
        dbCmUserPatient.setUpdateTime(new Date());
        cmUserPatientMapper.updateByPrimaryKeySelective(dbCmUserPatient);
    }

    /**
     * 设置默认的就诊人
     * @param cmUserPatient
     */
    @Transactional(rollbackFor = Exception.class)
    public void setDefaultPatient(CmUserPatient cmUserPatient) {
        CmUserPatient dbCmUserPatient = getCmUserPatientById(cmUserPatient.getCmPatientId());
        if (dbCmUserPatient == null) {
            throw new BusinessFailException("就诊人不存在");
        }
        Date updateTime = new Date();
        //将老的就诊人取消默认
        updateCmUserPatientIsDefault(cmUserPatient.getClinicId(),cmUserPatient.getCmUserId(),cmUserPatient.getUpdateUserId(),cmUserPatient.getUpdateBy(),updateTime);
        //将当前的就诊人设置为默认
        dbCmUserPatient.setIsDefault(YesOrNoEnum.YES.getValue());
        dbCmUserPatient.setUpdateUserId(cmUserPatient.getUpdateUserId());
        dbCmUserPatient.setUpdateBy(cmUserPatient.getUpdateBy());
        dbCmUserPatient.setUpdateTime(new Date());
        cmUserPatientMapper.updateByPrimaryKeySelective(dbCmUserPatient);
    }

    /**
     * 将老的就诊人取消默认
     * @param clinicId
     * @param cmUserId
     * @param updateUserId
     * @param updateBy
     * @param updateTime
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateCmUserPatientIsDefault(Long clinicId, Long cmUserId,Long updateUserId,String updateBy,Date updateTime) {
        CmUserPatientExample example = new CmUserPatientExample();
        CmUserPatientExample.Criteria criteria = example.createCriteria();
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andCmUserIdEqualTo(cmUserId);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        CmUserPatient cmUserPatient = new CmUserPatient();
        cmUserPatient.setIsDefault(YesOrNoEnum.NO.getValue());
        cmUserPatient.setUpdateUserId(updateUserId);
        cmUserPatient.setUpdateBy(updateBy);
        cmUserPatient.setUpdateTime(updateTime);
        cmUserPatientMapper.updateByExampleSelective(cmUserPatient,example);
    }
}
